from userscript_displayer import show_js


def show_script_window(main_root):
    """在主程序中嵌入脚本显示窗口"""
    show_js(
        r"""// ==UserScript==
// @name         超级K - 键盘刷视频(受控端)
// @namespace    https://scriptcat.org/zh-CN/script-show-page/3372
// @version      0.2
// @description  控制端监听按键，受控端接收按键消息后控制网页内容。用法举例：打游戏时在不切屏的情况下控制抖音网页端的上一个视频，下一个视频，播放和停止。
// @author       beibeibeibei
// @license      MIT
// @match        https://www.douyin.com/*
// @icon         
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    // 添加样式
    function add_css() {
        GM_addStyle(`
        .beibeibeibei-panel-warpper {
            width: 310px;
            height: 190px;
            position: fixed;
            top: 0;
            left: 0;
            display: flex;
            transition-timing-function: linear(0 0%, 0 1.8%, 0.01 3.6%, 0.03 6.35%, 0.07 9.1%, 0.13 11.4%, 0.19 13.4%, 0.27 15%, 0.34 16.1%, 0.54 18.35%, 0.66 20.6%, 0.72 22.4%, 0.77 24.6%, 0.81 27.3%, 0.85 30.4%, 0.88 35.1%, 0.92 40.6%, 0.94 47.2%, 0.96 55%, 0.98 64%, 0.99 74.4%, 1 86.4%, 1 100%);
            transition-duration: .3s;
            z-index: 1061;
        }

        .beibeibeibei-panel-warpper svg {
            vertical-align: initial;
        }

        .corner-box-warpper {
            .corner-box {
                background: transparent;
                opacity: 0;
                width: 310px;
                height: 190px;
                position: fixed;
                pointer-events: none;
            }

            .topright {
                z-index: -99999;
                top: 0;
                right: 0;
            }

            .bottomright {
                z-index: -99999;
                bottom: 0;
                right: 0;
            }

            .bottomleft {
                z-index: -99999;
                bottom: 0;
                left: 0;
            }

            .topleft {
                z-index: -99999;
                top: 0;
                left: 0;
            }
        }

        .beibeibeibei-panel-border {
            background: black;
            width: fit-content;
            height: fit-content;
            border-radius: 6px;
        }

        @keyframes movebackground {
            0% {
                background-position: 0% 50%;
            }

            50% {
                background-position: 100% 50%;
            }

            100% {
                background-position: 0% 50%;
            }
        }

        .beibeibeibei-panel-border.running {
            background: linear-gradient(45deg, rgb(84 58 181), rgb(84 58 181 / 70%), rgb(0 172 193 / 70%), rgb(87 228 246), rgb(255 255 255));
            animation: movebackground 4s infinite linear;
            background-size: 400%;
        }

        #beibeibeibei-panel {
            box-sizing: content-box;
            width: 300px;
            height: 180px;
            display: flex;
            flex-direction: column;
            background: black;
            padding: 2px;
            border: 1px solid white;
            border-radius: 6px;

            overflow: hidden;
            interpolate-size: allow-keywords;
            margin: 2px;
            transition-duration: 0.3s;
            transition-timing-function: linear(0 0%, 0 1.8%, 0.01 3.6%, 0.03 6.35%, 0.07 9.1%, 0.13 11.4%, 0.19 13.4%, 0.27 15%, 0.34 16.1%, 0.54 18.35%, 0.66 20.6%, 0.72 22.4%, 0.77 24.6%, 0.81 27.3%, 0.85 30.4%, 0.88 35.1%, 0.92 40.6%, 0.94 47.2%, 0.96 55%, 0.98 64%, 0.99 74.4%, 1 86.4%, 1 100%);
        }

        #beibeibeibei-panel .titlebar {
            display: flex;
            justify-content: flex-end;
            -webkit-user-select: none;
            user-select: none;
            container-name: titlebar;
            container-type: inline-size;
        }

        #beibeibeibei-panel .titlebar>* {
            width: 22px;
            height: 22px;
            padding: 0;
            overflow: hidden;
        }

        #beibeibeibei-panel .titlebar>*:not(:last-child) {
            margin-right: 2px;
        }

        @container titlebar (max-width: 120px) {

            /* 父容器宽度不够时不显示 */
            #beibeibeibei-panel .titlebar>*:not(:last-child) {
                display: none;
            }
        }

        #beibeibeibei-panel .titlebar>button {
            cursor: pointer;
        }

        #beibeibeibei-panel .titlebar>.led {
            border: 1px solid #767676;
            background-color: #efefef;
            border-radius: 3px;
            box-sizing: border-box;
            cursor: help;
            overflow: hidden;
        }

        @supports (rx: 0) {
            #beibeibeibei-panel .titlebar>.led ellipse {
                transform-origin: 10px 10px;
                fill: gray;
                rx: 7;
                ry: 1;
                transform: rotate(120deg);
                transition: all 0.3s ease-out;
            }
        }

        @supports not (rx: 0) {
            #beibeibeibei-panel .titlebar>.led ellipse {
                transform-origin: 10px 10px;
                fill: gray;
                transform: rotate(120deg) scaleX(1.4) scaleY(0.2);
                transition: all 0.3s ease-out;
            }
        }

        @keyframes flicker {

            0%,
            100% {
                transform: rotate(120deg) scale(1);
            }

            50% {
                transform: rotate(120deg) scale(1.2);
            }
        }

        @supports (rx: 0) {
            #beibeibeibei-panel .titlebar>.led.websocket-connected ellipse {
                animation: flicker 1.5s infinite;
                fill: #44ff00;
                rx: 5;
                ry: 5;
            }
        }

        @supports not (rx: 0) {
            #beibeibeibei-panel .titlebar>.led.websocket-connected ellipse {
                animation: flicker 1.5s infinite;
                fill: #44ff00;
            }
        }

        #beibeibeibei-panel .titlebar>.min .vline {
            opacity: 0;
        }

        #beibeibeibei-panel .msgs {
            flex-grow: 1;
            margin: 4px 0px;
            background: #2d2d2d;
            overflow-y: auto;
        }

        #beibeibeibei-panel .msgs .info,
        #beibeibeibei-panel .msgs .msg,
        #beibeibeibei-panel .msgs .error {
            color: #efefef;
            font-size: 9px;
            margin: 0;
        }

        #beibeibeibei-panel .msgs .error {
            color: #87ceeb;
        }

        #beibeibeibei-panel .footer {
            display: flex;
            height: 30px;
            min-height: 30px;
            justify-content: space-between;
        }

        #beibeibeibei-panel .footer>* {
            width: calc(50% - 2px);
            box-sizing: border-box;
            text-align: center;
            font-family: Arial, sans-serif;
        }

        #beibeibeibei-panel .footer>input {
            background: white;
            border: 2px solid gray;
            border-radius: 4px;
        }

        #beibeibeibei-panel .footer>.start {
            cursor: pointer;
            -webkit-user-select: none;
            user-select: none;
            white-space: nowrap;
        }

        /*隐藏输入框箭头*/
        .beibeibeibei-panel-warpper input::-webkit-outer-spin-button,
        .beibeibeibei-panel-warpper input::-webkit-inner-spin-button {
            -webkit-appearance: none !important;
            margin: 0;
        }

        @supports (-moz-appearance:none) {
            @-moz-document url-prefix() {
                .beibeibeibei-panel-warpper input[type="number"] {
                    -moz-appearance: textfield;
                    appearance: none;
                }
            }
        }

        #beibeibeibei-panel-rule-dialog {
            position: fixed;
            top: 50%;
            transform: translateY(round(-50%, 1px));
            border: none;
            border-radius: 6px;
            margin: 0 auto;
            padding: 0;
            box-shadow: 1px 1px 5px 2px white;

            &::backdrop {
                /* Safari 9+ */
                -webkit-backdrop-filter: blur(1px);
                backdrop-filter: blur(1px);
            }

            .title {
                width: 100%;
                height: 31px;
                background-color: black;
                display: flex;
                flex-direction: row-reverse;
                border-radius: 6px 6px 0 0;
                border-bottom: 1px solid #555;

                .close {
                    width: 46px;
                    height: 100%;
                    background-color: black;
                    color: white;
                    border-radius: 0 6px 0 0;
                    border: none;
                    cursor: pointer;
                    outline: none;

                    &:focus {
                        border: 1px solid white;
                    }

                    svg {
                        transition: all 0.1s;

                        line {
                            transition: all 0.1s;
                            transform-origin: center;
                        }
                    }

                    &:hover {
                        background-color: #0F0000;

                        svg {
                            transform: rotate(90deg);
                        }
                    }

                    &:active {
                        border: 1px solid darkred;

                        svg {
                            line {
                                transform: rotate(90deg);
                                stroke: red;
                            }
                        }
                    }
                }
            }

            .table {
                min-width: 180px;
                min-height: 100px;
                background-color: #222;
                color: white;
                border-radius: 0 0 6px 6px;
                padding: 10px;
                font-size: 12px;

                .column {
                    display: flex;
                    height: 40px;
                    background-color: black;

                    >* {
                        width: 100px;
                        overflow: hidden;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                    }

                    >*:not(:last-child) {
                        border-right: 1px solid gray;
                    }
                }

                .column.header {
                    border-radius: 6px 6px 0 0;
                    border: 1px solid gray;

                    >*:last-of-type {
                        /*不选中规则删除这个格子*/
                        -webkit-user-select: none;
                        user-select: none;
                    }
                }

                .column.body {
                    border: 1px solid gray;
                    border-top: none;

                    button.remove {
                        background-color: #111;
                        color: white;
                        border: 1px solid white;
                        border-radius: 4px;
                        cursor: pointer;
                        -webkit-user-select: none;
                        user-select: none;

                        &:hover {
                            border-color: #BBB;
                            box-shadow: inset 0px 0px 2px 0px white;
                        }

                        &:active {
                            border-color: #888;
                            color: #888;
                            transform: scale(0.95);
                        }
                    }
                }

                .column:last-of-type {
                    border-radius: 0 0 6px 6px;
                }


                .add {
                    width: 100%;
                    height: 40px;
                    cursor: pointer;
                    background-color: black;
                    color: white;
                    border: 1px solid white;
                    border-radius: 6px;
                    margin-top: 4px;
                    -webkit-user-select: none;
                    user-select: none;

                    &:hover {
                        box-shadow: inset 0px 0px 2px 0px white;
                    }

                    &:active {
                        transform: translate(1px, 1px);
                        width: calc(100% - 2px);
                    }
                }
            }
        }

        #beibeibeibei-panel-add-rule-dialog {
            position: fixed;
            top: 50%;
            transform: translateY(round(-50%, 1px));
            border: none;
            border-radius: 6px;
            margin: 0 auto;
            padding: 0;
            box-shadow: 0px 0px 5px 0px white;
            background-color: black;
            width: 470px;
            overflow: hidden;

            &::backdrop {
                /* Safari 9+ */
                -webkit-backdrop-filter: blur(1px);
                backdrop-filter: blur(1px);
            }

            .title {
                width: 100%;
                height: 31px;
                background-color: black;
                display: flex;
                flex-direction: row-reverse;
                border-bottom: 1px solid #555;

                .close {
                    width: 46px;
                    height: 100%;
                    background-color: black;
                    color: white;
                    border-radius: 0 6px 0 0;
                    border: none;
                    cursor: pointer;
                    outline: none;

                    &:focus {
                        border: 1px solid white;
                    }

                    svg {
                        transition: all 0.1s;

                        line {
                            transition: all 0.1s;
                            transform-origin: center;
                        }
                    }

                    &:hover {
                        background-color: #0F0000;

                        svg {
                            transform: rotate(90deg);
                        }
                    }

                    &:active {
                        border: 1px solid darkred;

                        svg {
                            line {
                                transform: rotate(90deg);
                                stroke: red;
                            }
                        }
                    }
                }
            }

            .add-panel {
                background-color: #222;
                color: white;
                padding: 10px;
                font-size: 12px;

                .add-panel-item {
                    margin-bottom: 10px;

                    input {
                        background-color: #2d3436;
                        color: #ecf0f1;
                        border: 1px solid #34495e;
                        border-radius: 4px;
                        font-size: 12px;
                        padding: 1px 3px;
                        outline: none;
                        text-align: center;
                        vertical-align: top;

                        &:focus {
                            border: 1px solid white;
                        }
                    }

                    input[type="number"] {
                        width: 30px;
                    }
                }

                .add-panel-item.text-center {
                    text-align: center;
                }
            }

            .footer {
                display: flex;
                justify-content: space-around;
                padding: 10px;
                border-top: 1px solid #555;
                background: black;
                -webkit-user-select: none;
                user-select: none;

                button {
                    background-color: #2d3436;
                    color: #ecf0f1;
                    border: 1px solid #34495e;
                    border-radius: 4px;
                    font-size: 12px;
                    padding: 6px 12px;
                    cursor: pointer;
                    outline: none;
                    transition: background-color 0.2s, transform 0.1s;

                    &:hover {
                        box-shadow: inset 0px 0px 5px 1px #3d4a51;
                    }

                    &:active {
                        transform: translate(1px, 1px);
                        background-color: #1a2023;
                    }

                    &:focus {
                        border: 1px solid white;
                    }
                }

                .add {
                    background-color: #05150b;
                }

                .cancel {
                    background-color: #170503;
                }
            }
        }

        /* 自定义select */
        @keyframes custom-select-expand {
            0% {
                display: none;
                height: 0px;
                overflow-y: auto;
            }

            1% {
                display: block;
                overflow-y: hidden;
            }

            99% {
                display: block;
                overflow-y: hidden;
            }

            100% {
                display: block;
                height: auto;
                overflow-y: auto;
            }
        }

        .custom-select {
            position: relative;
            display: inline-block;

            .select-button {
                vertical-align: top;
                background-color: #2d3436;
                color: #ecf0f1;
                border: 1px solid #34495e;
                border-radius: 4px;
                padding: 0px 3px;
                padding-right: 20px;
                font-size: 12px;
                text-align: center;
                background-repeat: no-repeat;
                background-position: right 2px top 2px;
                outline: none;
                cursor: pointer;
            }

            .select-button:focus {
                border: 1px solid white;
            }

            .options-container {
                position: absolute;
                left: 0;
                width: 100%;
                font-size: 12px;
                background-color: #2d3436;
                border: none;
                border-radius: 4px;
                overflow-y: auto;
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
                z-index: 10;
                white-space: nowrap;
                height: 0px;
                interpolate-size: allow-keywords;
            }


            .options-container::-webkit-scrollbar {
                width: 6px;
                background: #202324;
                border-radius: 0 3px 3px 0;
            }

            .options-container::-webkit-scrollbar-thumb {
                background: #454a4d;
                border-radius: 3px;
            }

            .options-container::-webkit-scrollbar-thumb:hover {
                background: #575e62;
            }

            .option-item {
                background-color: #2d3436;
                color: #ecf0f1;
                padding: 4px 0px;
                text-align: center;
                cursor: pointer;
            }

            .option-item:hover {
                background: #777;
            }

            .option-item:focus {
                background: #777;
            }

            .option-item:focus-visible {
                outline: none;
                background: #777;
            }
        }

        /* 选项向上展开 */
        .custom-select.position-above {
            .select-button {
                background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0 0 11 11'%3e%3cpolygon%20points='3,6 5,4 7,6'%20style='fill:white;stroke:white;stroke-width:1'/%3e%3c/svg%3e");
            }

            .options-container {
                bottom: calc(100% + 1px);
            }

        }

        /* 选项向下展开 */
        .custom-select.position-below {
            .select-button {
                background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0 0 11 11'%3e%3cpolygon%20points='3,4 5,6 7,4'%20style='fill:white;stroke:white;stroke-width:1'/%3e%3c/svg%3e");
            }

            .options-container {
                top: calc(100% + 1px);
            }
        }

        /* 选项右侧展开 */
        .custom-select.position-right {
            .select-button {
                background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0 0 11 11'%3e%3cpolygon%20points='4,6 6,4 4,2' style='fill:white;stroke:white;stroke-width:1'/%3e%3c/svg%3e");
            }

            .options-container {
                top: calc(50%);
                left: calc(100% + 1px);
                transform: translateY(-50%);
            }
        }
    `);
    }

    // 动态插入 HTML 结构
    function add_HTML() {
        const panelWrapper = document.createElement('div');
        panelWrapper.className = 'beibeibeibei-panel-warpper';
        document.body.appendChild(panelWrapper);
        panelWrapper.innerHTML = `
        <div class="corner-box-warpper">
            <div class="corner-box topright"></div>
            <div class="corner-box bottomright"></div>
            <div class="corner-box bottomleft"></div>
            <div class="corner-box topleft"></div>
        </div>
        <div class="beibeibeibei-panel-border">
            <div id="beibeibeibei-panel">
                <div class="titlebar">
                    <div class="led" title="连接状态">
                        <svg width="20" height="20">
                            <ellipse cx="10" cy="10" rx="5" ry="5"></ellipse>
                        </svg>
                    </div>
                    <!-- svg制作方式：Inkscape→全选形状→1+1+17x17,文件→文档属性→19x19 -->
                    <button class="home" title="项目主页" type="button">
                        <a href="https://gitee.com/beibeibeibei/SuperK" target="_blank" rel="noopener noreferrer">
                            <svg width="19" height="19" viewbox="0 0 19 19">
                                <path
                                    d="M 12.238437,2 C 15.140188,2 17,4.5155458 17,7.9010931 17,10.528328 14.801,13.421712 10.468437,16.672867 a 1.701,1.8389227 0 0 1 -1.9368745,0 C 4.1990001,13.421712 2,10.528328 2,7.9010931 2,4.5155458 3.8598126,2 6.7615625,2 7.8095,2 8.5203125,2.3958792 9.5,3.2940567 10.479875,2.3960819 11.1905,2 12.238437,2 Z"
                                    fill="black" />
                            </svg>
                        </a>
                    </button>
                    <button class="rule" title="设置规则" type="button">
                        <svg width="19" height="19">
                            <path d="M11,0 L0,11 L7,18 L18,7 L18,0 Z M12,6 m-3,0 a3,3 0 1,0 6,0 a3,3 0 1,0-6,0"
                                fill-rule="evenodd" fill="black" />
                        </svg>
                    </button>
                    <button class="test" title="发送测试消息" type="button">
                        <svg width="19" height="19">
                            <polygon points="1,3 9,8 17,3" fill="black"></polygon>
                            <polygon points="1,5 1,15 17,15 17,5 9,10" fill="black"></polygon>
                        </svg>
                    </button>
                    <button class="cls" title="清空消息记录" type="button">
                        <svg width="19" height="19">
                            <polygon points="12,1 0,13 2,15 9,15 14.5,9.5 14,8 8,14 3,14 2,13 10,5 14.5,9.5 17.5,6.5"
                                fill="black" />
                            <polygon points="18,17 18,16 0,16 0,17" fill="black" />
                        </svg>
                    </button>
                    <button class="move" title="移动窗口位置" type="button">
                        <svg width="19" height="19">
                            <polygon points="1,1 1,5 5,1" fill="black" />
                            <polygon points="17,1 13,1 17,5" fill="black" />
                            <polygon points="1,17 1,13 5,17" fill="black" />
                            <polygon points="17,17 17,13 13,17" fill="black" />
                        </svg>
                    </button>
                    <button class="min" title="缩小面板" type="button">
                        <svg width="19" height="19">
                            <rect x="2" y="8" width="14" height="2" fill="black" />
                            <rect class="vline" x="8" y="2" width="2" height="14" fill="black" />
                        </svg>
                    </button>
                </div>
                <div class="msgs"></div>
                <div class="footer">
                    <input class="port" name="port" value="6789" type="number" min="0" max="65535" title="端口号">
                    <button class="start" type="button">启动</button>
                </div>
            </div>
        </div>
        <dialog id="beibeibeibei-panel-rule-dialog">
            <div class="title">
                <button class="close" aria-label="关闭规则面板" type="button">
                    <svg width="10" height="10">
                        <line x1="0" y1="0" x2="10" y2="10" stroke="white" />
                        <line x1="0" y1="10" x2="10" y2="0" stroke="white" />
                    </svg>
                </button>
            </div>
            <div class="table">
                <div class="column header">
                    <div>规则名</div>
                    <div>网址包含文字</div>
                    <div>选择器A</div>
                    <div>选择器A数量限制</div>
                    <div>选择器B</div>
                    <div title="从0开始">选择器B的第几项</div>
                    <div>对选择器B的操作</div>
                    <div>操作数据</div>
                    <div>规则删除</div>
                </div>
                <button class="add" type="button">
                    <div>添加新规则</div>
                </button>
            </div>
        </dialog>
        <dialog id="beibeibeibei-panel-add-rule-dialog">
            <div class="focus-start" tabindex="0"></div>
            <div class="title">
                <button class="close" aria-label="关闭添加规则对话框" type="button">
                    <svg width="10" height="10">
                        <line x1="0" y1="0" x2="10" y2="10" stroke="white" />
                        <line x1="0" y1="10" x2="10" y2="0" stroke="white" />
                    </svg>
                </button>
            </div>
            <div class="add-panel">
                <div class="add-panel-item">1.收到 <input class="rule-name" title="规则名称" name="rule-name"
                        spellcheck="false"> 消息
                </div>
                <div class="add-panel-item">2.网站地址包含 <input class="url-pattern" title="网址匹配文本" name="url-pattern"
                        spellcheck="false">
                </div>
                <div class="add-panel-item">
                    3.选择器 <input class="count-based-selector" title="选择器(数量限制)" name="count-based-selector"
                        spellcheck="false"> 的数量
                    <div class="quantitySelector custom-select position-right" title="数量限制条件" name="quantity-condition"
                        aria-label="数量限制条件">
                        <button class="select-button" type="button">请选择</button>
                        <div class="options-container" tabindex="-1">
                            <div class="option-item" data-value="1" tabindex="-1">无限制</div>
                            <div class="option-item" data-value="2" tabindex="-1">最少</div>
                            <div class="option-item" data-value="3" tabindex="-1">最多</div>
                            <div class="option-item" data-value="4" tabindex="-1">等于</div>
                            <div class="option-item" data-value="5" tabindex="-1">范围</div>
                        </div>
                    </div>
                    <span>
                        <span class="single-input">
                            <input type="number" class="quantity-value" title="数量值" name="quantity-value"
                                spellcheck="false"> 个
                        </span>
                        <span class="range-input">
                            在 <input type="number" class="min-quantity" title="最小数量" name="min-quantity"
                                spellcheck="false"> ~
                            <input type="number" class="max-quantity" title="最大数量" name="max-quantity"
                                spellcheck="false"> 之间
                        </span>
                    </span>
                </div>
                <div class="add-panel-item text-center">满足上述条件时将执行第4条</div>
                <div class="add-panel-item">
                    4.选择器 <input class="action-selector" title="目标选择器" name="action-selector" spellcheck="false"> 的第
                    <input type="number" class="action-index" title="目标选择器索引(从0开始)" name="action-index"
                        spellcheck="false"> 项会被
                    <div class="action-type custom-select position-right" title="对最终目标的操作" name="action-type"
                        aria-label="对最终目标的操作">
                        <button class="select-button" type="button">请选择</button>
                        <div class="options-container" tabindex="-1">
                            <div class="option-item" data-value="1" tabindex="-1">点击</div>
                            <div class="option-item" data-value="2" tabindex="-1">旋转</div>
                            <div class="option-item" data-value="3" tabindex="-1">缩放</div>
                        </div>
                    </div>
                    <input type="number" class="action-num" title="操作数据" name="action-num" spellcheck="false">
                </div>
            </div>
            <div class="footer">
                <button class="add" type="button">添加</button>
                <button class="test" type="button">模拟输入</button>
                <button class="cancel" type="button">返回</button>
            </div>
            <div class="focus-end" tabindex="0"></div>
        </dialog>
        `;
    }

    function beibeibeibei_init() {
        /* 关闭dialog1 */
        document.querySelector("#beibeibeibei-panel-rule-dialog .title .close").addEventListener("click", (e) => {
            e.target.closest('dialog').parentElement.querySelectorAll('dialog').forEach((d) => {
                d.close();
            })
        });
        /* 打开添加规则弹窗 */
        document.querySelector("#beibeibeibei-panel-rule-dialog .table .add").addEventListener("click", (e) => {
            document.querySelector('#beibeibeibei-panel-add-rule-dialog').showModal();
        });
        /* 关闭dialog2 title */
        document.querySelector("#beibeibeibei-panel-add-rule-dialog .title .close").addEventListener("click", (e) => {
            e.target.closest('dialog').close();
        });
        /* 关闭dialog2 返回*/
        document.querySelector("#beibeibeibei-panel-add-rule-dialog .footer .cancel").addEventListener("click", (e) => {
            e.target.closest('dialog').close();
        });

        /* 打开规则弹窗 */
        document.querySelector("#beibeibeibei-panel .rule").addEventListener("click", () => {
            /** @type {HTMLDialogElement} */
            let dialog = document.querySelector("#beibeibeibei-panel-rule-dialog");
            dialog.showModal();
        });

        /* 清空消息记录 */
        document.querySelector("#beibeibeibei-panel .cls").addEventListener("click", () => {
            let msgs = document.querySelector("#beibeibeibei-panel .msgs");
            msgs.replaceChildren();
        });

        // #region /* 缩小面板 */
        let panelIsMin = false;
        document.querySelector("#beibeibeibei-panel .min").addEventListener("click", () => {
            panelIsMin = !panelIsMin;

            let vl = document.querySelector("#beibeibeibei-panel .min .vline");
            vl.style.opacity = panelIsMin ? '1' : '0';
            vl.parentElement.parentElement.title = panelIsMin ? "恢复面板" : "缩小面板";

            let panel = document.querySelector("#beibeibeibei-panel");
            panel.style.width = panelIsMin ? "22px" : "300px";
            panel.style.height = panelIsMin ? "22px" : "180px";
        });
        // #endregion

        // #region /* 移动位置 */
        let panelpos = 3;
        document.querySelector("#beibeibeibei-panel .move").addEventListener("click", () => {
            panelpos = (panelpos + 1) % 4;
            updatePos();
        });
        function updatePos() {
            const wrapper = document.querySelector("#beibeibeibei-panel").parentElement.parentElement;
            const positions = [getComputedStyle(document.querySelector(".beibeibeibei-panel-warpper .topright")), getComputedStyle(document.querySelector(".beibeibeibei-panel-warpper .bottomright")), getComputedStyle(document.querySelector(".beibeibeibei-panel-warpper .bottomleft")), getComputedStyle(document.querySelector(".beibeibeibei-panel-warpper .topleft"))];

            wrapper.style.inset = positions[panelpos].inset;
            switch (panelpos) {
                case 0:
                    wrapper.style.alignItems = "flex-start";
                    wrapper.style.justifyContent = "flex-end";
                    break;
                case 1:
                    wrapper.style.alignItems = "flex-end";
                    wrapper.style.justifyContent = "flex-end";
                    break;
                case 2:
                    wrapper.style.alignItems = "flex-end";
                    wrapper.style.justifyContent = "flex-start";
                    break;
                case 3:
                    wrapper.style.alignItems = "flex-start";
                    wrapper.style.justifyContent = "flex-start";
                    break;
            }
        };
        const debounce = (fn, delay) => {
            let timer;
            return function () {
                if (timer) {
                    clearTimeout(timer);
                }
                timer = setTimeout(() => {
                    fn();
                }, delay);
            }
        };
        const cancalDebounce = debounce(updatePos, 200);

        window.addEventListener('resize', cancalDebounce);
        // #endregion
        /* 按下 ESC 键时关闭弹窗 */
        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                let dialog = document.querySelector("#beibeibeibei-panel-rule-dialog");
                dialog.close();
                let dialog2 = document.querySelector("#beibeibeibei-panel-add-rule-dialog");
                dialog2.close();
            }
        });

        // #region /* add-rule-dialog弹窗循环tab键功能 */
        const focusStart = document.querySelector("#beibeibeibei-panel-add-rule-dialog > div.focus-start")
        focusStart.addEventListener("focus", (event) => {
            let els = document.querySelector('#beibeibeibei-panel-add-rule-dialog').querySelectorAll("input, select, button");
            els[els.length - 1].focus();
        });
        const focusEnd = document.querySelector("#beibeibeibei-panel-add-rule-dialog > div.focus-end");
        focusEnd.addEventListener("focus", (event) => {
            let els = document.querySelector('#beibeibeibei-panel-add-rule-dialog').querySelectorAll("input, select, button");
            els[0].focus();
        });
        // #endregion

        // #region /* 根据选中的选项显示或隐藏对应的<span>元素 */
        const quantitySelector = document.querySelector('#beibeibeibei-panel-add-rule-dialog .quantitySelector');
        const inputSingle = document.querySelector('#beibeibeibei-panel-add-rule-dialog .add-panel-item .single-input');
        const inputRange = document.querySelector('#beibeibeibei-panel-add-rule-dialog .add-panel-item .range-input');
        inputSingle.style.display = 'none';
        inputRange.style.display = 'none';
        quantitySelector.addEventListener('change', function () {
            const selectedValue = this.querySelector('.select-button').getAttribute('data-value');
            // 根据选择值显示对应输入
            switch (selectedValue) {
                case '1': // 无限制
                default: // 其他情况隐藏所有输入
                    inputSingle.style.display = 'none';
                    inputRange.style.display = 'none';
                    break;
                case '2': // 最少
                case '3': // 最多
                case '4': // 等于
                    inputSingle.style.display = 'inline';
                    inputRange.style.display = 'none';
                    break;
                case '5': // 范围
                    inputSingle.style.display = 'none';
                    inputRange.style.display = 'inline';
                    break;
            }
        });
        // #endregion

        // #region /* 监听 dialog 关闭事件, 重置其中的内容 */
        const dialog2 = document.querySelector('#beibeibeibei-panel-add-rule-dialog');
        dialog2.addEventListener('close', () => {
            // 重置
            dialog2.querySelectorAll('input').forEach(input => {
                input.value = '';
            });
            // 重置.custom-select组件
            dialog2.querySelectorAll('.custom-select').forEach(customSelect => {
                const selectButton = customSelect.querySelector('.select-button');
                const optionsContainer = customSelect.querySelector('.options-container');
                selectButton.textContent = '请选择';
                selectButton.removeAttribute('data-value');
                optionsContainer.style.animation = 'none';// 移除现有动画
                void optionsContainer.offsetWidth;// 强制触发重绘以重置动画
            });
            // 隐藏动态输入区域
            dialog2.querySelectorAll('.single-input, .range-input').forEach(el => {
                el.style.display = 'none';
            });
        });
        // #endregion

        // #region /* 自定义select处理 */
        document.querySelectorAll('.custom-select').forEach(customSelect => {
            const selectButton = customSelect.querySelector('.select-button');
            const optionsContainer = customSelect.querySelector('.options-container');
            let isOpen = false;

            selectButton.addEventListener('click', function (e) {
                // 切换选项可见性
                e.stopPropagation();
                if (isOpen) {
                    resetAndPlay(optionsContainer, 'reverse');
                    customSelect.querySelectorAll('.option-item').forEach(option => {
                        option.setAttribute('tabindex', '-1');
                    })
                } else {
                    resetAndPlay(optionsContainer, 'normal');
                    customSelect.querySelectorAll('.option-item').forEach(option => {
                        option.setAttribute('tabindex', '0');
                    })
                }
                isOpen = !isOpen;
            });

            customSelect.querySelectorAll('.option-item').forEach(option => {
                // 点击事件处理
                option.addEventListener('click', function () {
                    selectButton.textContent = this.textContent;
                    selectButton.setAttribute('data-value', this.dataset.value);
                    if (isOpen) {
                        resetAndPlay(optionsContainer, 'reverse');
                        isOpen = false;
                    }
                    // 触发自定义的 change 事件
                    const changeEvent = new Event('change', { bubbles: true });
                    customSelect.dispatchEvent(changeEvent);
                });
                // 键盘事件处理
                option.addEventListener('keydown', function (e) {
                    switch (e.key) {
                        case 'Enter':
                        case ' ':{
                            e.preventDefault();
                            this.click();
                            selectButton.focus();
                            break;
                        }
                        case 'ArrowDown':{
                            e.preventDefault();
                            const next = this.nextElementSibling || optionsContainer.firstElementChild;
                            next.focus();
                            break;
                        }
                        case 'ArrowUp':{
                            e.preventDefault();
                            const prev = this.previousElementSibling || optionsContainer.lastElementChild;
                            prev.focus();
                            break;
                        }
                        case 'ArrowLeft':
                        case 'ArrowRight':{
                            // 按左键或右键时, 将焦点返回到select-button
                            e.preventDefault();
                            selectButton.focus();
                            break;
                        }
                    }
                });
            });
            document.addEventListener('click', function () {
                // 点击页面其他区域关闭选项
                if (isOpen) {
                    resetAndPlay(optionsContainer, 'reverse');
                    isOpen = false;
                }
            });
            optionsContainer.addEventListener('click', function (e) {
                // 防止选项容器点击时冒泡
                e.stopPropagation();
            });
            selectButton.addEventListener('keydown', function (e) {
                switch (e.key) {
                    case 'ArrowLeft':
                    case 'ArrowRight':
                        // 按左键或右键时, 将焦点切换到option里
                        if (isOpen) {
                            e.preventDefault();
                            customSelect.querySelector('.option-item')?.focus();
                        }
                        break;
                }
            });
        });
        function resetAndPlay(el, direction) {
            // 移除现有动画
            el.style.animation = 'none';
            // 强制触发重绘以重置动画
            void el.offsetWidth;
            // 应用新动画设置
            el.style.animation = `custom-select-expand 0.1s ease-out ${direction} forwards`;
        }
        // #endregion

        // #region /* 模拟输入按钮 */
        let testBtn = document.querySelector("#beibeibeibei-panel-add-rule-dialog button.test");
        testBtn.addEventListener('click', () => {
            const dialog2 = testBtn.closest("dialog");

            // 填充文本输入框
            dialog2.querySelector('.rule-name').value = '旋转视频示例';
            dialog2.querySelector('.url-pattern').value = 'yin.com';
            dialog2.querySelector('.count-based-selector').value = 'video';
            dialog2.querySelector('.action-selector').value = 'video';
            dialog2.querySelector('.action-index').value = '0';

            // 设置数量条件选择器为"最多"
            const quantitySelector = dialog2.querySelector('.quantitySelector');
            const quantityButton = quantitySelector.querySelector('.select-button');
            quantityButton.textContent = '最多';
            quantityButton.dataset.value = '3';
            quantitySelector.dispatchEvent(new Event('change'));

            // 填充数量值
            dialog2.querySelector('.quantity-value').value = '1';

            // 设置操作类型为"点击"
            const actionTypeSelector = dialog2.querySelector('.action-type');
            const actionButton = actionTypeSelector.querySelector('.select-button');
            actionButton.textContent = '旋转';
            actionButton.dataset.value = '2';
            actionTypeSelector.dispatchEvent(new Event('change'));

            // 填充操作数值
            dialog2.querySelector('.action-num').value = '90'; // 新增字段
        })
        // #endregion

        // #region /* 添加新条目 */
        function collectRuleData() {
            let dialog2 = document.querySelector("#beibeibeibei-panel-add-rule-dialog");
            return {
                ruleName: dialog2.querySelector('.rule-name').value.trim(),
                urlPattern: dialog2.querySelector('.url-pattern').value.trim(),
                selectorA: dialog2.querySelector('.count-based-selector').value.trim(),
                quantityCondition: dialog2.querySelector('.quantitySelector .select-button').textContent,
                quantityValue: getQuantityValues(dialog2),
                selectorB: dialog2.querySelector('.action-selector').value.trim(),
                actionIndex: dialog2.querySelector('.action-index').value.trim(),
                actionType: dialog2.querySelector('.action-type .select-button').textContent,
                actionNum: dialog2.querySelector('.action-num').value.trim()
            };
        }
        function getQuantityValues(dialog) {
            const condition = dialog.querySelector('.quantitySelector .select-button').dataset.value;
            switch (condition) {
                case '2': // 最少
                case '3': // 最多
                case '4': // 等于
                    return dialog.querySelector('.quantity-value').value;
                case '5': // 范围
                    return `${dialog.querySelector('.min-quantity').value}-${dialog.querySelector('.max-quantity').value}`;
                default:
                    return '';
            }
        }
        function validateRuleData(data) {
            if (!data.ruleName) {
                alert("规则名称不能为空");
                return false;
            }
            if (data.quantityCondition !== "无限制" && !data.selectorA) {
                alert("选择器A不能为空");
                return false;
            }
            if (!data.selectorB) {
                alert("选择器B不能为空");
                return false;
            }
            if (isNaN(data.actionIndex) || data.actionIndex < 0) {
                alert("索引值必须是非负数字");
                return false;
            }
            return true;
        }
        function addRuleToStorage(ruleData) {
            const rules = GM_getValue('rulesData', []);
            const newRule = [
                ruleData.ruleName,
                ruleData.urlPattern,
                ruleData.selectorA,
                formatQuantityCondition(ruleData.quantityCondition, ruleData.quantityValue),
                ruleData.selectorB,
                ruleData.actionIndex,
                ruleData.actionType,
                ruleData.actionNum
            ];
            rules.push(newRule);
            GM_setValue('rulesData', rules);
        }
        function formatQuantityCondition(condition, value) {
            switch (condition) {
                case '无限制': return '无限制';
                case '最少': return `最少 ${value} 个`;
                case '最多': return `最多 ${value} 个`;
                case '等于': return `等于 ${value} 个`;
                case '范围': return `范围 ${value} 个`;
                default: return '无限制';
            }
        }
        function addRuleToUI(ruleData) {
            const ruleDialog = document.querySelector('#beibeibeibei-panel-rule-dialog');
            const newBody = document.createElement('div');
            newBody.className = 'column body';

            const fields = [
                ruleData.ruleName,
                ruleData.urlPattern,
                ruleData.selectorA,
                formatQuantityCondition(ruleData.quantityCondition, ruleData.quantityValue),
                ruleData.selectorB,
                ruleData.actionIndex,
                ruleData.actionType,
                ruleData.actionNum
            ];

            fields.forEach(text => {
                const div = document.createElement('div');
                div.textContent = text;
                newBody.appendChild(div);
            });

            // 添加删除按钮
            const deleteDiv = document.createElement('div');
            const delBtn = document.createElement('button');
            delBtn.className = 'remove';
            delBtn.textContent = '删除此条';
            delBtn.onclick = function () {
                const bodyElement = this.closest('.column.body');
                const index = bodyElement.dataset.index;
                // 从页面中删除元素
                bodyElement.remove();
                // 从存储的数据中删除对应条目
                const savedData = GM_getValue('rulesData', []);
                savedData.splice(index, 1);
                GM_setValue('rulesData', savedData);
            };
            deleteDiv.appendChild(delBtn);
            newBody.appendChild(deleteDiv);

            // 插入到添加按钮之前
            const addBtn = ruleDialog.querySelector('.add');
            ruleDialog.querySelector('.table').insertBefore(newBody, addBtn);
        }
        let addBtn = document.querySelector("#beibeibeibei-panel-add-rule-dialog button.add");
        addBtn.addEventListener('click', () => {
            const ruleData = collectRuleData();
            if (validateRuleData(ruleData)) {
                addRuleToStorage(ruleData);
                addRuleToUI(ruleData);
                addBtn.closest("dialog").close();
            }
        });
        // #endregion
    };

    function beibeibeibei_socket() {
        const startButton = document.querySelector("#beibeibeibei-panel .start");
        const testButton = document.querySelector("#beibeibeibei-panel .test");
        const portInput = document.querySelector("#beibeibeibei-panel input.port");
        const pborder = document.querySelector(".beibeibeibei-panel-border");
        const msgContainer = document.querySelector("#beibeibeibei-panel .msgs");
        /** @type {HTMLElement} */
        const led = document.querySelector("#beibeibeibei-panel .led");

        // 获取端口号
        const port = portInput.value.trim();
        // 定义 WebSocket 的 URL
        const wsUrl = `ws://localhost:${port}`;
        // 定义 WebSocket 实例和定时器
        /** @type {WebSocket} */
        let ws;
        let websocketCheckInterval;
        let websocketCheckIntervalTime = 1000;
        let messageCleanupInterval;
        let messageCleanupIntervalTime = 5000;
        // isrunning只是建议启动, 和 WebSocket 状态无关
        let isrunning = false;

        // 启动连接
        startButton.addEventListener("click", () => {
            isrunning = !isrunning;
            // 修改UI
            if (isrunning) {
                startButton.textContent = '停止';
                pborder.classList.add("running");
            } else {
                startButton.textContent = '启动';
                pborder.classList.remove("running");
            }
            // 控制 Websocket
            if (isrunning) {
                // 如果 WebSocket 已经存在, 先关闭它
                if (ws) {
                    ws.close();
                }

                // 创建新的 WebSocket 实例
                ws = new WebSocket(wsUrl);

                // 设置定时器, 间隔 intervalTimeout 毫秒检查一次 WebSocket 状态
                websocketCheckInterval = setInterval(() => {
                    if (ws.readyState === WebSocket.CLOSING || ws.readyState === WebSocket.CLOSED) {
                        console.log("WebSocket 状态为 CLOSING 或 CLOSED, 尝试重新连接...");
                        appendMessage("info", `尝试重新连接`);
                        // 关闭当前 WebSocket 实例
                        ws.close();
                        // 创建新的 WebSocket 实例
                        ws = new WebSocket(wsUrl);
                        // 添加 WebSocket 的事件监听
                        ws.onopen = handleWebSocketOpen;
                        ws.onmessage = handleWebSocketMessage;
                        ws.onerror = handleWebSocketError;
                        ws.onclose = handleWebSocketClose;
                    }
                }, websocketCheckIntervalTime);

                // 设置定时器, 控制消息容器中的子元素数量
                messageCleanupInterval = setInterval(() => {
                    const childrenCount = msgContainer.childElementCount;
                    if (childrenCount > 50) {
                        // 计算要删除的前 5% 子元素的数量
                        const deleteCount = Math.ceil(childrenCount * 0.05);
                        // 删除前 5% 的子元素
                        requestIdleCallback(() => {
                            for (let i = 0; i < deleteCount; i++) {
                                if (msgContainer.childElementCount > 0) {
                                    msgContainer.removeChild(msgContainer.firstChild);
                                }
                            }
                        });
                    }
                }, messageCleanupIntervalTime);

                // 添加 WebSocket 的事件监听
                ws.onopen = handleWebSocketOpen;
                ws.onmessage = handleWebSocketMessage;
                ws.onerror = handleWebSocketError;
                ws.onclose = handleWebSocketClose;
            } else {
                // 停止定时器
                if (websocketCheckInterval) {
                    clearInterval(websocketCheckInterval);
                    websocketCheckInterval = null;
                }

                // 停止定时器
                if (messageCleanupInterval) {
                    clearInterval(messageCleanupInterval);
                    messageCleanupInterval = null;
                }

                // 关闭 WebSocket 连接
                if (ws) {
                    ws.close();
                    ws = null;
                }

                console.log("WebSocket 连接已停止");
            }
        });

        // WebSocket 连接成功
        function handleWebSocketOpen() {
            console.log("WebSocket 连接成功");
            appendMessage("info", `已连接 WebSocket 服务器：${wsUrl}`);
            led.classList.add("websocket-connected");
            led.title = "连接状态: 已连接";
        }

        // WebSocket 收到消息
        function handleWebSocketMessage(/** @type { MessageEvent } */event) {
            console.log("收到消息：", event.data);
            appendMessage("msg", event.data);

            // 处理消息并执行规则
            beibeibeibei_processRules(event.data);
        }

        // WebSocket 发生错误
        function handleWebSocketError(event) {
            console.log("WebSocket 发生错误：", event);
            appendMessage("error", "WebSocket 连接错误");
        }

        // WebSocket 连接关闭
        function handleWebSocketClose(event) {
            console.log("WebSocket 已关闭");
            appendMessage("info", `WebSocket 连接已断开`);
            led.classList.remove("websocket-connected");
            led.title = "连接状态: 未连接";
        }

        // 测试按钮点击事件
        testButton.addEventListener("click", () => {
            if (ws && ws.readyState === WebSocket.OPEN) {
                // 发送测试消息
                const testMessage = "测试消息";
                ws.send(testMessage);
                appendMessage("info", `已发送测试消息：${testMessage}`);
            } else {
                appendMessage("error", "WebSocket 连接未开启, 无法发送测试消息");
            }
        });

        // 显示消息
        function appendMessage(className, textContent) {
            const msg = document.createElement("p");
            msg.className = className;
            msg.textContent = textContent;
            msgContainer.appendChild(msg);

            // 获取滚动条位置和容器高度信息
            const isNearBottom = msgContainer.scrollTop + msgContainer.clientHeight >= msgContainer.scrollHeight * 0.9;
            // 如果滚动条接近底部，则滚动到底部
            if (isNearBottom) {
                msgContainer.scrollTop = msgContainer.scrollHeight;
            }
        }
    }

    function runWhenDocumentReady(...funcs) {
        const validFuncs = [...new Set(funcs)].filter(item => typeof item === 'function');

        if (document.readyState === 'loading') {
            validFuncs.forEach(func =>
                               document.addEventListener('DOMContentLoaded', func)
                              );
        } else {
            validFuncs.forEach(func => func());
        }
    }

    // const gmStorage = {
    //     rulesData: [
    //         ['msg1', '', 'button', '无限制', '.testA', '0', '旋转', '90'],
    //         ['msg1', '', 'button', '无限制', '.testA', '0', '缩放', '1.1'],
    //         ['msg1', '', 'button', '无限制', '.testA', '0', '点击', ''],
    //         ['msg-test', '', '.test-element', '最少 6 个', '.test-element', '0', '旋转', '135']
    //     ]
    // };

    // 保存规则数据
    function beibeibeibei_saveRulesData() {
        const bodyElements = document.querySelectorAll('#beibeibeibei-panel-rule-dialog .column.body');
        const savedData = [];

        bodyElements.forEach((element, index) => {
            const children = element.children;
            const rowData = [];
            for (let i = 0; i < children.length; i++) {
                if (i === children.length - 1) {
                    // 跳过最后一个包含按钮的div
                    continue;
                }
                rowData.push(children[i].textContent.trim());
            }
            savedData.push(rowData);
        });

        GM_setValue('rulesData', savedData);
        console.log('规则数据已保存');
    }

    // 恢复规则数据
    function beibeibeibei_restoreRulesData() {
        const savedData = GM_getValue('rulesData', []);
        const headerElement = document.querySelector('#beibeibeibei-panel-rule-dialog .column.header');
        const addageElement = document.querySelector('#beibeibeibei-panel-rule-dialog .add');
        const bodyElements = document.querySelectorAll('#beibeibeibei-panel-rule-dialog .column.body');

        // 清除现有的body元素
        bodyElements.forEach(element => {
            element.remove();
        });

        // 恢复保存的内容
        savedData.forEach((rowData, index) => {
            const newBody = document.createElement('div');
            newBody.className = 'column body';
            newBody.dataset.index = index;

            if (rowData.length < 8) {
                rowData = rowData.concat([null]);
            }

            rowData.forEach((data) => {
                const div = document.createElement('div');
                div.textContent = data || '';
                newBody.appendChild(div);
            });

            // 添加删除按钮
            const deleteDiv = document.createElement('div');
            const delBtn = document.createElement('button');
            delBtn.className = 'remove';
            delBtn.textContent = '删除此条';
            delBtn.type = 'button';
            delBtn.onclick = function () {
                const bodyElement = this.closest('.column.body');
                const index = bodyElement.dataset.index;
                // 从页面中删除元素
                bodyElement.remove();
                // 从存储的数据中删除对应条目
                const savedData = GM_getValue('rulesData', []);
                savedData.splice(index, 1);
                GM_setValue('rulesData', savedData);
            };
            deleteDiv.appendChild(delBtn);
            newBody.appendChild(deleteDiv);

            // 插入到header和add按钮之间
            headerElement.parentNode.insertBefore(newBody, addageElement);
        });
    }

    // 执行规则
    function beibeibeibei_processRules(message) {
        // 获取所有保存的规则
        const rules = GM_getValue('rulesData', []);
        // 过滤规则
        const filteredRules = rules.filter(item => {
            // 确保 item 是数组且数组不为空
            if (!Array.isArray(item) || item.length < 8) return false;
            // 检查第 0 项是否匹配 message
            const messageMatch = item[0] === message;
            // 检查 URL 是否包含第 1 项
            const urlMatch = urlContainsText(item[1]);
            // 检查元素数量是否满足条件
            const selector2 = item[2]; // 第2项是选择器
            const condition = item[3]; // 第3项是条件
            const elementCountMatch = checkElementCount(selector2, condition);
            // 检查第4项选择器的数量是否大于等于第5项
            const selector4 = item[4]; // 第4项是选择器
            const selector4Count = parseInt(item[5]); // 第5项是第几项(从0开始)
            const selector4CountMatch = checkElementCount(selector4, `最少 ${selector4Count + 1} 个`);
            // 返回所有条件都满足的规则
            // console.log({messageMatch, urlMatch, elementCountMatch, selector4CountMatch});
            return messageMatch && urlMatch && elementCountMatch && selector4CountMatch;
        });

        console.log({ 0: 'beibeibeibei_processRules的filteredRules结果', message, filteredRules });

        // 执行符合条件的规则
        filteredRules.forEach((rule) => {
            const elements = document.querySelectorAll(rule[4]);
            if (elements.length > parseInt(rule[5])) {
                const targetIndex = parseInt(rule[5]);
                const targetElement = elements[targetIndex];

                // 执行操作
                switch (rule[6]) {
                    case '点击':{
                        if (typeof targetElement.click === 'function') {
                            targetElement.click();
                        } else {
                            targetElement.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
                        }
                        break;
                    }
                    case '旋转':{
                        const rotateValue = parseInt(rule[7]) || 0;
                        let targetElementRotate = parseInt(getComputedStyle(targetElement).rotate) || 0;
                        targetElement.style.rotate = `${(targetElementRotate + rotateValue) % 360}deg`;
                        break;
                    }
                    case '缩放':{
                        const scaleValue = rule[7];
                        targetElement.style.transform = `scale(${scaleValue})`;
                        break;
                    }
                }
            }
        });
    }
    // 正则匹配当前网址
    function urlMatchesPattern(pattern) {
        const currentUrl = window.location.href;
        const regex = new RegExp(pattern);
        return regex.test(currentUrl);
    }
    // 普通文本匹配当前网址
    function urlContainsText(text) {
        const currentUrl = window.location.href;
        return currentUrl.includes(text);
    }
    // 检查元素数量
    function checkElementCount(selector, condition) {
        if (condition === '无限制') {
            // 无限制的意思就是无限制, 有没有元素都行, 选择器无效都行
            return true;
        }
        // 验证选择器是否有效
        if (!selector || typeof selector !== 'string' || selector.trim() === '') {
            // console.error('无效的选择器:', selector);
            return false; // 或抛出更明确的错误
        }

        // 获取匹配指定 CSS 选择器的元素个数
        const elements = document.querySelectorAll(selector);
        const count = elements.length;

        // 解析条件
        let min = 0;
        let max = Infinity;
        let exact = null;
        let range = null;

        // 正则表达式用于提取数字
        const numberRegex = /\d+/g;

        // 根据条件类型解析
        if (condition === '无限制') {
            // 无限制的意思就是无限制, 有没有元素都行
            return true;
        } else if (condition.startsWith('最少')) {
            // 最少 N 个
            const numbers = condition.match(numberRegex);
            if (numbers && numbers.length > 0) {
                min = parseInt(numbers[0]);
                return count >= min;
            }
        } else if (condition.startsWith('最多')) {
            // 最多 N 个
            const numbers = condition.match(numberRegex);
            if (numbers && numbers.length > 0) {
                max = parseInt(numbers[0]);
                return count <= max;
            }
        } else if (condition.startsWith('等于')) {
            // 等于 N 个
            const numbers = condition.match(numberRegex);
            if (numbers && numbers.length > 0) {
                exact = parseInt(numbers[0]);
                return count === exact;
            }
        } else if (condition.startsWith('范围')) {
            // 范围 A-B 个
            const numbers = condition.match(numberRegex);
            if (numbers && numbers.length === 2) {
                min = parseInt(numbers[0]);
                max = parseInt(numbers[1]);

                // 如果颠倒, 自动调换
                if (min > max) {
                    [min, max] = [max, min];
                }

                return count >= min && count <= max;
            }
        } else {
            console.error('不支持的条件格式');
            return false;
        }

        return false;
    }

    runWhenDocumentReady(add_HTML);
    runWhenDocumentReady(beibeibeibei_socket, beibeibeibei_restoreRulesData, beibeibeibei_init);
    runWhenDocumentReady(add_css);


    //     // 用于临时测试
    //     setTimeout(() => {
    //         // 添加测试目标元素
    //         const testArea = document.createElement("div");
    //         testArea.className = "test-area"; // 添加样式类
    //         testArea.id = "test-area";
    //         testArea.style.position = 'fixed';
    //         testArea.style.top = '200px';
    //         testArea.style.left = '200px';
    //         testArea.style.width = "300px";
    //         testArea.style.height = "200px";
    //         testArea.style.background = "linear-gradient(135deg,#FFD26F 15%,#3677FF 100%)";
    //         testArea.style.padding = "20px";
    //         testArea.style.display = "flex";
    //         testArea.style.flexWrap = "wrap";
    //         testArea.style.justifyContent = "flex-start";
    //         testArea.style.alignItems = "flex-start";
    //         document.body.appendChild(testArea);

    //         // 添加一些可点击、可旋转、可缩放的元素
    //         for (let i = 0; i < 6; i++) {
    //             const testElement = document.createElement("div");
    //             testElement.className = "test-element";
    //             testElement.style.margin = "10px";
    //             testElement.style.width = "80px";
    //             testElement.style.height = "60px";
    //             testElement.style.display = "flex";
    //             testElement.style.justifyContent = "center";
    //             testElement.style.alignItems = "center";
    //             testElement.style.backgroundColor = "#e0e0e0";
    //             testElement.style.borderRadius = "5px";
    //             testElement.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.2)";
    //             testElement.style.cursor = "pointer";
    //             testElement.style.fontSize = "14px";
    //             testElement.style.transition = "all 0.3s ease";

    //             testElement.innerHTML = `<span>测试元素 ${i + 1}</span>`;

    //             testElement.addEventListener("click", function () {
    //                 console.log(`测试元素 ${i + 1} 被点击了`);
    //             });

    //             testArea.appendChild(testElement);
    //         }

    //         document.querySelector("#beibeibeibei-panel > div.titlebar > button.rule").click();
    //         beibeibeibei_processRules('msg-test');
    //     }, 40);
})();""",
        parent=main_root,
    )
